package com.newbe.security.utils;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.*;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: Newbe
 * @Date: 2020/3/30 16:31
 * @Description: Password加密工具
 *
 */
public class PasswordEncoderFactoriesUtil {

    public static PasswordEncoder createDelegatingPasswordEncoder() {

        String encodingId = "bcrypt";
        Map<String, PasswordEncoder> encoders= new HashMap<>();
        encoders.put(encodingId, new BCryptPasswordEncoder());
        encoders.put("ldap", new LdapShaPasswordEncoder());
        encoders.put("MD4", new Md4PasswordEncoder());
        encoders.put("MD5", new MessageDigestPasswordEncoder("MD5"));
        encoders.put("noop", NoOpPasswordEncoder.getInstance());
        encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
        encoders.put("scrypt", new SCryptPasswordEncoder());
        encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
        encoders.put("SHA-256", new MessageDigestPasswordEncoder("SHA-256"));
        encoders.put("sha256", new StandardPasswordEncoder());
        return new DelegatingPasswordEncoder(encodingId, encoders);
    }

    public static void main(String[] args) {

        PasswordEncoder passwordEncoder = PasswordEncoderFactoriesUtil.createDelegatingPasswordEncoder();
        /**
         * @Description: PasswordEncoder接口方法解析
         *         public interface PasswordEncoder {
         *
         *          加密(外面调用一般在注册的时候加密前端传过来的密码保存进数据库)
         *     String encode(CharSequence rawPassword);
         *
         *          加密前后匹配(encodedPassword：对明文加密后的密码，rawPassword：加了密的数据库密码）
         *      boolean matches(CharSequence encodedPassword, String rawPassword);
         *
         *          是否需要再次进行编码, 默认不需要
         *      default boolean upgradeEncoding(String encodedPassword) {
         *      return false;
         *  }
         *  }
        **/

        //1.对 123456 加密两次，验证两次的密码
        String pd1 = passwordEncoder.encode("123456");
        String pd2 = passwordEncoder.encode("123456");
        System.out.println("pd1:"+pd1);
        System.out.println("pd2:"+pd2);
        System.out.println("pd1和pd2密码内容是否一致:"+pd1.equals(pd2));//false

        //2.对 123456 能否匹配到 加密后的密码
        boolean flag1 = passwordEncoder.matches("123456", pd1);
        boolean flag2 = passwordEncoder.matches("123456", pd2);
        System.out.println("pd1密码是否匹配成功:"+flag1);//true
        System.out.println("pd2密码是否匹配成功:"+flag2);//true

        //3.对123456 进行MD5加密，在对加密后的字符串加上{MD5},让密码管理器识别加密密码的类型
        String md5encode = DigestUtils.md5DigestAsHex("123456".getBytes());//spring工具自带的MD5加密
        System.out.println(md5encode);//e10adc3949ba59abbe56e057f20f883e
        String myMd5encode = "{MD5}e10adc3949ba59abbe56e057f20f883e";
        System.out.println("MD5："+passwordEncoder.matches("123456", myMd5encode));



    }

}
